var LoginController = function(){
	
	this.loginModel = new LoginModel();
	this.loginView = new LoginView();
	
	this.apiServiceModel = new ApiServiceModel();
	this.apiServiceView = new ApiServiceView();
	
	this.requestModel = new RequestModel();
	this.requestView = new RequestView();
	
	var thisController = this;
	
	var load = function(){
		thisController.loginView.onLogin.subscribe(sendLogin);
		thisController.loginView.onLogOut.subscribe(doLogOut);
		
		thisController.loginModel.onLoad.subscribe(doLoad);
		thisController.loginModel.onLogin.subscribe(doLogin);
		thisController.loginModel.onLoginError.subscribe(doLoginError);
		thisController.loginModel.load();
		
		thisController.apiServiceView.onApiSelected.subscribe(doApiSelected);
		thisController.apiServiceView.onServiceSelected.subscribe(doServiceSelected);
		
		thisController.apiServiceModel.onLoad.subscribe(doLoadServices);
		thisController.apiServiceModel.load();
		
		thisController.requestView.onSendRequest.subscribe(doSendRequest);
		
		thisController.requestModel.onLoad.subscribe(doLoadRequest);
		thisController.requestModel.onResponse.subscribe(doResponse);
		thisController.requestModel.loadEnums();
		
		doLogOut();
	};
	
	var doLoad = function(environments){
		var array = new Array();
		for (var i = 0; i < environments.length; i++) {
			array[i] = environments[i].scheme + "://" + environments[i].host;
		}
		thisController.loginView.setEnvironments(array);
	};
	
	var sendLogin = function(loginParameters){
		var selectedEnv = loginParameters.environment;
		var environment = thisController.loginModel._environments[selectedEnv];
		thisController.loginModel.sendLogin(loginParameters.username, loginParameters.password, environment);
	};
	
	var doLogin = function(user) {
		thisController.loginView.setLoggedIn(user);
		thisController.apiServiceView.enable(true);
	};
	
	var doLoginError = function(loginError) {
		thisController.loginView.onLogginError(loginError.status, loginError.response);
		doLogOut();
	};
	
	var doApiSelected = function(apiIndex){
		var api = thisController.apiServiceModel._services[apiIndex];
		var services = api.services;
		var array = new Array();
		for (var i = 0; i < services.length; i++) {
			array[i] = services[i];
		}
		thisController.apiServiceView.setServices(array);
	};
	
	var doLoadServices = function(apiServices){
		var array = new Array();
		for (var i = 0; i < apiServices.length; i++) {
			array[i] = apiServices[i].api;
		}
		thisController.apiServiceView.setApis(array);
		doApiSelected(0);
	};
	
	var doLogOut = function(){
		thisController.loginView.setLoggedOut();
		thisController.apiServiceView.enable(false);
		thisController.requestView.enable(false);
	};
	
	var doServiceSelected = function(service){
		var api = thisController.apiServiceModel._services[service.apiIndex];
		var apiService = api.services[service.serviceIndex];
		thisController.requestModel.load(api.api, apiService);
	};
	
	var doLoadRequest = function(service){
		
		var restParams = service.rest.parameters;
		var reflectionParams = service.reflection.parameters;
		
		var array = new Array();
		for (var i = 0; i < restParams.length; i++) {
			var isFile = (reflectionParams[i].type == "InputStream");
			array[i] = {'name': restParams[i].name, 'isFile': isFile};
		}
		thisController.requestView.setFields(array);
		
		for (var i = 0; i < restParams.length; i++) {
			var type = reflectionParams[i].type;
			if(reflectionParams[i].genericTypes){
				var generic = reflectionParams[i].genericTypes[0];
				type += '&lt;' + generic.type + '&gt;';
				if(generic.enum && reflectionParams[i].type == "List"){
					var enumValues = thisController.requestModel._enums[generic.type];
					thisController.requestView.setListEnumValues(restParams[i].name, enumValues);
				}
			}
			thisController.requestView.setFieldType(restParams[i].name, type);
			if(reflectionParams[i].enum){
				var enumValues = thisController.requestModel._enums[reflectionParams[i].type];
				thisController.requestView.setEnumValues(restParams[i].name, enumValues);
			}
			if(!restParams[i].notNull){
				thisController.requestView.setFieldNull(true, restParams[i].name);
			}
			if(restParams[i].name == "oauthtoken"){
				var access = thisController.loginModel._user.accessKey;
				thisController.requestView.setFieldValue(restParams[i].name, access);
			}
			if(reflectionParams[i].type == "InputStream"){
				thisController.requestView.setFileEvents(restParams[i].name);
			}
		}
		thisController.requestView.setLabel({'verb':service.rest.verb, 'path': service.rest.path});
		
		thisController.requestView.enable(true);
	};
	
	var doSendRequest = function(parameters){
		var service = thisController.requestModel._service;
		var environment = thisController.loginModel._environment;
		if(service.rest.consumes && service.rest.consumes[0] == "multipart/form-data"){
			var path = environment.scheme + "://" + environment.host + service.rest.path;
			var restParams = service.rest.parameters;
			for (var i = 0; i < restParams.length; i++) {
				if(restParams[i].type == "PATH"){
					var name = restParams[i].name;
					var value = parameters[name];
					path = path.replace("\{" + name + "\}", value);
				}
			}
			thisController.requestView.setMultipart(service.rest.verb, path);
		}
		else{
			var user = thisController.loginModel._user;
			thisController.requestModel.sendRequest(environment, service.rest, user, parameters);
		}
	};
	
	var doResponse = function(data){
		var response = JSON.stringify(data, null, 4);
		thisController.requestView.setResponse(response);
	};
	
	load();
};